package com.bbx.taxi.client.widget.Drag;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import butterknife.InjectView;

import com.baidu.location.BDLocation;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import com.bbx.androidapi.util.ToastUtil;
import com.bbx.taxi.client.MyApplication.OnLocationResultListener;
import com.bbx.taxi.official.R;
import com.bbx.taxi.client.Activity.Address.SelectCityActivity;
import com.bbx.taxi.client.Adapter.PayDetailsAdapter;
import com.bbx.taxi.client.Adapter.Chat.SearchCityAdapter;
import com.bbx.taxi.client.Adapter.City.CityAdapter;
import com.bbx.taxi.client.Bean.City;
import com.bbx.taxi.client.Bean.Value;
import com.bbx.taxi.client.Bean.Attribute.MainAttribute;
import com.bbx.taxi.client.Bean.Extra.AddressMsg;
import com.bbx.taxi.client.DB.CityDB;
import com.bbx.taxi.client.DB.LineDB;
import com.bbx.taxi.client.Task.MyLineTask;
import com.bbx.taxi.client.Task.MyLineTask.OnLineFinishListener;
import com.bbx.taxi.client.Util.FormatUtil;
import com.bbx.taxi.client.Util.ToCity;
import com.bbx.taxi.client.widget.City.BladeView;
import com.bbx.taxi.client.widget.City.PinnedHeaderListView;
import com.bbx.taxi.client.widget.City.BladeView.OnItemClickListener;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ViewDragHelper;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnTouchListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.bbx.taxi.client.MyApplication;
import com.example.loadview.LoadingDialog;

import android.view.View.OnClickListener;
/**
 * Created by Flavien Laurent (flavienlaurent.com) on 23/08/13.
 */
public class CityDragLayout extends ViewGroup  implements TextWatcher, MyApplication.EventHandler ,OnLocationResultListener,OnLineFinishListener{
	public static final int SELECTCITY_RESULT_CODE=10;
	ImageButton mClearSearchBtn;
	 View mCityContainer;
	View mSearchContainer;
	PinnedHeaderListView mCityListView;
	BladeView mLetter;
	ListView mSearchListView;
	private List<City> mCities;
	private SearchCityAdapter mSearchCityAdapter;
	private CityAdapter mCityAdapter;
	// 首字母集
	private List<String> mSections;
	// 根据首字母存放数据
	private Map<String, List<City>> mMap;
	// 首字母位置集
	private List<Integer> mPositions;
	// 首字母对应的位置
	private Map<String, Integer> mIndexer;
	private CityDB mCityDB;
	private InputMethodManager mInputMethodManager;
	List<City> cityList=new ArrayList<City>();
	private LineDB db_line;// 线路数据库
	/**目的地或出发地*/
	private int intentType;
	private String start_address_name="";
	private boolean isInCity=false;
	public MyApplication mApplication;
	public LoadingDialog loaddialog;
	ImageView iv_city_delete;
	public int Location_length=-1;
	/**
	 * 该拖动试图的开关状态
	 * 
	 */
	public interface OnCityDragViewStatusListener {
		/** 该拖动试图的开关状态 */
		public void onDragViewStatus(boolean isOpen);
		/** 该拖动试图的点击城市监听 */
		public void onClickCity(String city,String is_detail);
	};

	public OnCityDragViewStatusListener mOnCityDragViewStatusListener;

	public void setOnCityDragViewStatusListener(OnCityDragViewStatusListener l) {
		mOnCityDragViewStatusListener = l;
	};

	private final ViewDragHelper mDragHelper;
	private View mDescView;

	private float mInitialMotionX;
	private float mInitialMotionY;
	/** 可拖动范围（总范围） */
	private int mDragRange;
	private int mTop;
	/** 拖动偏移=拖动的量/可拖动的范围（总范围） 大于0.5f则代表为超过一半 */
	private float mDragOffset;
	private Context context;

	public CityDragLayout(Context context) {
		this(context, null);
		this.context=context;
	}

	public CityDragLayout(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
		this.context=context;
	}

	public CityDragLayout(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		this.context=context;
		mDragHelper = ViewDragHelper.create(this, 1f, new DragHelperCallback());
	}

	@Override
	protected void onFinishInflate() {
		mApplication=MyApplication.getInstance();
		loaddialog = new LoadingDialog(context, true);
		mDescView = findViewById(R.id.desc);
		mClearSearchBtn=(ImageButton)mDescView.findViewById(R.id.ib_clear_text);
		mCityContainer=(View)mDescView.findViewById(R.id.city_content_container);
		mSearchContainer=(View)mDescView.findViewById(R.id.search_content_container);
		mCityListView=(PinnedHeaderListView)mDescView.findViewById(R.id.citys_list);
		mLetter=(BladeView)mDescView.findViewById(R.id.citys_bladeview);
		mSearchListView=(ListView)mDescView.findViewById(R.id.search_list);
	}

	/**
	 * 显示最大化，及View滑到原始位置
	 */
	public void maximize() {
		initView();
		initData();
		mDescView.setVisibility(View.VISIBLE);
		if (mOnCityDragViewStatusListener != null){
			mOnCityDragViewStatusListener.onDragViewStatus(true);
		}
	}

	/**
	 * 显示最小化，及View滑出屏幕
	 */
	public void minimize() {
		mDescView.setVisibility(View.GONE);
		if (mOnCityDragViewStatusListener != null){
			mOnCityDragViewStatusListener.onDragViewStatus(false);
		}
	}

	private class DragHelperCallback extends ViewDragHelper.Callback {

		/**
		 * 确定当前子view是否可拖动，
		 */
		@Override
		public boolean tryCaptureView(View child, int pointerId) {
			return child == mDescView;
		}

		/**
		 * 该方法在子view位置发生改变时都会被调用，可以在这个方法中做一些拖动过程中渐变的动画等操作,left距离左边的偏移量
		 */
		@Override
		public void onViewPositionChanged(View changedView, int left, int top,
				int dx, int dy) {
			mDragOffset = (float) left / mDragRange;
			mDescView.setPivotX(mDescView.getWidth());

			mDescView.setAlpha(1 - mDragOffset);

			invalidate();
			if (mDragOffset >= 1) {
				if (mOnCityDragViewStatusListener != null)
					mOnCityDragViewStatusListener.onDragViewStatus(false);
			} else if (mDragOffset <= 0) {
				if (mOnCityDragViewStatusListener != null)
					mOnCityDragViewStatusListener.onDragViewStatus(true);
			}
		}

		/**
		 * 该方法在手势拖动释放的时候被调用，可以在这里设置子View预期到达的位置，
		 * 如果人为的手势拖动没有到达预期位置，我们可以让子View在人为的拖动结束后，再自动关的滑动到指定位置
		 * 
		 * @xvel为X轴的拖动速度正的为向右，0代表滑动停止后一段时间后，释放手指
		 * @yvel为Y轴拖动速度正的为向下
		 */
		@Override
		public void onViewReleased(View releasedChild, float xvel, float yvel) {
			int left = getPaddingLeft();
			// 如果方向向右，或者停止滑动却拖动便宜大于可滑动的一半，则滑动总范围，及整个View滑出屏幕
			// 如果这句话没执行，则代表滑到原始位置。
			if (xvel > 0 || (xvel == 0 && mDragOffset > 0.5f)) {
				left += mDragRange;
			}
			mDragHelper.settleCapturedViewAt(left, 0);
			invalidate();
		}

		/**
		 * 从字面意思就可以看出这是一个获取边界的方法
		 */
		@Override
		public int getViewVerticalDragRange(View child) {
			return mDragRange;
		}

		// @Override
		// public int clampViewPositionVertical(View child, int top, int dy) {
		// final int topBound = getPaddingTop();
		// final int bottomBound = getHeight() - mHeaderView.getHeight() -
		// mHeaderView.getPaddingBottom();
		//
		// final int newTop = Math.min(Math.max(top, topBound), bottomBound);
		// return newTop;
		// }
		/**
		 * 此方法是用来控制水平方向移动的范围，每次调用
		 * 拿到当前的left值跟DragLayout的根布局的paddingleft值做比较，取两者中大的值
		 * ，这样做是为了防止子view左边滑出根布局的左边界。 拿left和padding
		 * left中的较大值跟可滑动范围的右边界（根布局宽度减去子view的宽度）作比较，取较小值，这样做是为了防止子view右边滑出根布局右边界。
		 */
		@Override
		public int clampViewPositionHorizontal(View child, int left, int dx) {
			final int leftBound = getPaddingLeft();
			final int rightBound = getWidth() - 0;

			final int newLeft = Math.min(Math.max(left, leftBound), rightBound);

			return newLeft;
		}
	}

	@Override
	public void computeScroll() {
		if (mDragHelper.continueSettling(true)) {
			ViewCompat.postInvalidateOnAnimation(this);
		}
	}
//
//	@Override
//	public boolean onInterceptTouchEvent(MotionEvent ev) {
//		final int action = MotionEventCompat.getActionMasked(ev);
//
//		if ((action != MotionEvent.ACTION_DOWN)) {
//			mDragHelper.cancel();
//			return super.onInterceptTouchEvent(ev);
//		}
//
//		if (action == MotionEvent.ACTION_CANCEL
//				|| action == MotionEvent.ACTION_UP) {
//			mDragHelper.cancel();
//			return false;
//		}
//
//		final float x = ev.getX();
//		final float y = ev.getY();
//		boolean interceptTap = false;
//		switch (action) {
//		case MotionEvent.ACTION_DOWN: {
//			mInitialMotionX = x;
//			mInitialMotionY = y;
//			interceptTap = mDragHelper.isViewUnder(mDescView, (int) x, (int) y);
//			break;
//		}
//
//		case MotionEvent.ACTION_MOVE: {
//			final float adx = Math.abs(x - mInitialMotionX);
//			final float ady = Math.abs(y - mInitialMotionY);
//			final int slop = mDragHelper.getTouchSlop();
//			/* useless */
//			if (ady > slop && adx > ady) {
//				mDragHelper.cancel();
//				return false;
//			}
//		}
//		}
//
//		return mDragHelper.shouldInterceptTouchEvent(ev) || interceptTap;
//	}
//
//	@Override
//	public boolean onTouchEvent(MotionEvent ev) {
//		mDragHelper.processTouchEvent(ev);
//
//		final int action = ev.getAction();
//		final float x = ev.getX();
//		final float y = ev.getY();
//		boolean isDescViewUnder = mDragHelper.isViewUnder(mDescView, (int) x,
//				(int) y);
//		switch (action & MotionEventCompat.ACTION_MASK) {
//		case MotionEvent.ACTION_DOWN: {
//			mInitialMotionX = x;
//			mInitialMotionY = y;
//			break;
//		}
//
//		case MotionEvent.ACTION_UP: {
//			final float dx = x - mInitialMotionX;
//			final float dy = y - mInitialMotionY;
//			final int slop = mDragHelper.getTouchSlop();
//			if (dx * dx + dy * dy < slop * slop && isDescViewUnder) {
//				// if (mDragOffset == 0) {
//				// smoothSlideTo(1f);
//				// } else {
//				// smoothSlideTo(0f);
//				// }
//			}
//			break;
//		}
//		}
//
//		return isViewHit(mDescView, (int) x, (int) y);
//	}

	private boolean isViewHit(View view, int x, int y) {
		int[] viewLocation = new int[2];
		view.getLocationOnScreen(viewLocation);
		int[] parentLocation = new int[2];
		this.getLocationOnScreen(parentLocation);
		int screenX = parentLocation[0] + x;
		int screenY = parentLocation[1] + y;
		return screenX >= viewLocation[0]
				&& screenX < viewLocation[0] + view.getWidth()
				&& screenY >= viewLocation[1]
				&& screenY < viewLocation[1] + view.getHeight();
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		measureChildren(widthMeasureSpec, heightMeasureSpec);

		int maxWidth = MeasureSpec.getSize(widthMeasureSpec);
		int maxHeight = MeasureSpec.getSize(heightMeasureSpec);

		setMeasuredDimension(
				resolveSizeAndState(maxWidth, widthMeasureSpec, 0),
				resolveSizeAndState(maxHeight, heightMeasureSpec, 0));
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		// 初始化可拖动范围===整个布局的宽度=整个屏幕宽度
		mDragRange = getWidth();
		// 默认左上角位置
		 mDescView.layout(0, mTop, r, mTop + b);
		// 默认右上角位置，及屏幕外面
//		mDescView.layout(r, mTop, r + mDescView.getMeasuredWidth(), mTop + b);
	}
	
	
	
	

	@Override
	public void beforeTextChanged(CharSequence s, int start, int count,
			int after) {
		// do nothing
	}

	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {
		mSearchCityAdapter = new SearchCityAdapter(context,
				mCities);
		mSearchListView.setAdapter(mSearchCityAdapter);
		mSearchListView.setTextFilterEnabled(true);
		if (mCities.size() < 1 || TextUtils.isEmpty(s)) {
			mCityContainer.setVisibility(View.VISIBLE);
			mSearchContainer.setVisibility(View.INVISIBLE);
			mClearSearchBtn.setVisibility(View.GONE);
		} else {
			mClearSearchBtn.setVisibility(View.VISIBLE);
			mCityContainer.setVisibility(View.INVISIBLE);
			mSearchContainer.setVisibility(View.VISIBLE);
			mSearchCityAdapter.getFilter().filter(s);
		}
	}

	@Override
	public void afterTextChanged(Editable s) {
		if (!s.toString().isEmpty()) {
			iv_city_delete.setVisibility(View.VISIBLE);
		}
		else{
			iv_city_delete.setVisibility(View.GONE);
		}

	}
	@Override
	public void onCityComplite() {
		// 城市列表加载完的回调函数
		mCities = mApplication.getCityList();
		mSections = mApplication.getSections();
		mMap = mApplication.getMap();
		mPositions = mApplication.getPositions();
		mIndexer = mApplication.getIndexer();

		mCityAdapter = new CityAdapter(context, mCities, mMap,
				mSections, mPositions);
//		【暂时隐藏】
		mLetter.setVisibility(View.VISIBLE);
		mCityListView.setAdapter(mCityAdapter);
		mCityListView.setOnScrollListener(mCityAdapter);
		mCityListView.setPinnedHeaderView(LayoutInflater.from(
				context).inflate(
				R.layout.biz_plugin_weather_list_group_item, mCityListView,
				false));
		// mActionBar.setProgressBarVisibility(View.INVISIBLE);
	}

	@Override
	public void onNetChange() {
		// TODO Auto-generated method stub

	}

	@Override
	public void onLocationResult(BDLocation location) {
	}
	public void onLocationResult(ReverseGeoCodeResult result) {
	}
	@Override
	public void onLocationFail(boolean isnet) {
		// TODO Auto-generated method stub
		
	}
	/**
	 * 设置市内
	 */
	public void setIsInCity(boolean isInCity){
		this.isInCity=isInCity;
	}
	public void setType(int intentType){
		this.intentType=intentType;
	}
	public void setStartName(String start_address_name){
		this.start_address_name=start_address_name;
	}
	public void setaddTextChangedListener(EditText edittext,ImageView iv_city_delete){
		this.iv_city_delete=iv_city_delete;
		edittext.addTextChangedListener(this);
	}
	protected void initView() {
		mApplication.setEventHandler(this);
		db_line=new LineDB(context);
		if(mApplication.loctionCity==null||mApplication.loctionCity.equals("")||mApplication.loctionCity.equals("null")){
			mApplication.setOnLocationResultListener(this);
			mApplication.onStartLocation();
		}
		mCityListView.setEmptyView(findViewById(R.id.tv_nocity));
		mLetter.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(String s) {
				if (mIndexer.get(s) != null) {
					mCityListView.setSelection(mIndexer.get(s));
				}
			}
		});
		mLetter.setVisibility(View.GONE);
		mSearchListView.setEmptyView(findViewById(R.id.search_empty));
		mSearchContainer.setVisibility(View.GONE);
		mCityListView
				.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {

					@Override
					public void onItemClick(AdapterView<?> parent, View view,
							int position, long id) {
						//获取定位城市的长度
					if(mSections!=null&&mSections.size()>0&&mSections.get(0).equals(CityAdapter.Location_title)){
						Location_length=mMap.get(mSections.get(0)).size();
					}
					//用于不能点击定位城市
//                  if(position<Location_length){
					if(false){

								return;
						}else{
						minimize();
			    		if (mOnCityDragViewStatusListener != null){
							mOnCityDragViewStatusListener.onDragViewStatus(false);
							String detail= mCityAdapter.getItem(position).getIs_detail();
							if(detail!=null&&detail.equals(Value.CITY_DETAIL)){
							}else{
								detail=Value.CITY_NODETAIL;
							}
							mOnCityDragViewStatusListener.onClickCity(mCityAdapter.getItem(position).getCity(),detail);
			    		}
					  }
					}
				});

		mSearchListView
				.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {

					@Override
					public void onItemClick(AdapterView<?> parent, View view,
							int position, long id) {
						minimize();
						if (mOnCityDragViewStatusListener != null){
							mOnCityDragViewStatusListener.onDragViewStatus(false);
							mOnCityDragViewStatusListener.onClickCity(mSearchCityAdapter.getItem(position).getCity(), mSearchCityAdapter.getItem(position).getIs_detail());
			    		}
					}
				});
	}
	protected void initData() {
		mCityDB = mApplication.getCityDB();
		mInputMethodManager = (InputMethodManager) context.getSystemService(context.INPUT_METHOD_SERVICE);
		if(isInCity){
			ToCity.setInCityList(context);
		}
		else{
         //城市列表有数据
		if (mApplication.isCityListComplite()) {
			mCities = mApplication.getCityList();
			mSections = mApplication.getSections();
			mMap = mApplication.getMap();
			mPositions = mApplication.getPositions();
			mIndexer = mApplication.getIndexer();

			mCityAdapter = new CityAdapter(context, mCities,
					mMap, mSections, mPositions);
			mCityListView.setAdapter(mCityAdapter);
			mCityListView.setOnScrollListener(mCityAdapter);
			mCityListView.setPinnedHeaderView(LayoutInflater.from(
					context).inflate(
					R.layout.biz_plugin_weather_list_group_item, mCityListView,
					false));
//		      【暂时隐藏】
			mLetter.setVisibility(View.VISIBLE);

		}
		else{
//			mCities=new ArrayList<City>();
//			mCities.clear();
//			mCityAdapter = new CityAdapter(context, mCities,
//					mMap, mSections, mPositions);
//			mCityListView.setAdapter(mCityAdapter);
//			ToCity.setLocalCityList(context);
			mCityListView.setEmptyView(findViewById(R.id.tv_nocity));
			findViewById(R.id.citys_list_empty).setVisibility(View.GONE);
		 }
		}
	}
	/**
	 * 获取线路
	 */
	private void getOnLine() {
		if(loaddialog!=null&&!loaddialog.isShowing()){
			loaddialog.show();
		}
		MyLineTask.getInstance(context).setOnLineFinishListener(this);	
	}
	@Override
	public void onLineFinish(boolean isisSuccess) {
		if(loaddialog!=null){
			loaddialog.onDismiss();
		}
		if(isisSuccess){
		switch (intentType) {
		case AddressMsg.ADDRESS_START_MAIN:
		case AddressMsg.ADDRESS_START_CHANGE:
			ToCity.setCityList(context);
			break;
		case AddressMsg.ADDRESS_END_MAIN:
		case AddressMsg.ADDRESS_END_CHANGE:
			if (start_address_name.equals("")) {
				ToCity.setCityList(context);
			}
			else{
				ToCity.setToCityList(context, start_address_name);	
			}
		
			break;
		}
		}else{
			ToastUtil.showToast(context, R.string.no_network);
		}
	}
}
